package com.ctl.szmd.szmd.utils

import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Handler
import androidx.core.content.FileProvider
import com.blankj.utilcode.util.*
import com.tencent.mmkv.MMKV
import okhttp3.ResponseBody
import java.io.*


/**
 * created by : chentl
 * Date: 2020/07/31
 */
class DownloadUtils {

    companion object {
        const val DOWNLOAD_ID_APK = "download_id_apk"
        private var downloadManager: DownloadManager? = null

        /**
         * 检查下载状态
         */
        fun checkDownloadProgress(downloadId: Long, handler: Handler?): Int {
            var progress = 0
            val query = DownloadManager.Query()
            query.setFilterById(downloadId)
            if (downloadManager == null) {
                downloadManager =
                    Utils.getApp().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
            }
            if (downloadManager == null) {
                return -1
            }
            val cursor = downloadManager!!.query(query)
            if (cursor.moveToFirst()) {
                val states = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
                when (states) {
                    DownloadManager.STATUS_PAUSED -> {
//                        LogUtils.i("下载暂停")
                        handler?.obtainMessage(DownloadManager.STATUS_PAUSED)?.sendToTarget()
                    }
                    DownloadManager.STATUS_PENDING -> {
//                        LogUtils.i("准备下载")
                        handler?.obtainMessage(DownloadManager.STATUS_PENDING)?.sendToTarget()
                    }
                    DownloadManager.STATUS_RUNNING -> {
//                        LogUtils.i("正在下载")
                        //计算下载下载率
                        val totalSize: Int =
                            cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))
                        val currentSize =
                            cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))
                        progress =
                            (currentSize.toFloat() / totalSize.toFloat() * 100).toInt()
//                        LogUtils.i(progress)
                        handler?.obtainMessage(DownloadManager.STATUS_RUNNING, progress)
                            ?.sendToTarget()
                    }
                    DownloadManager.STATUS_SUCCESSFUL -> {
//                        ToastUtils.showShort("下载完成")
                        progress = 100
                        handler?.obtainMessage(DownloadManager.STATUS_SUCCESSFUL, downloadId)
                            ?.sendToTarget()
                    }
                    DownloadManager.STATUS_FAILED -> {
                        progress = -1
//                        ToastUtils.showShort("下载失败")
                        handler?.obtainMessage(DownloadManager.STATUS_FAILED)?.sendToTarget()
                    }
                }
            } else {
//                LogUtils.i("取消下载")
                progress = -1
                handler?.obtainMessage(404)?.sendToTarget()
            }
            cursor.close()
            return progress
        }

        /**
         * 根据downloadID获取本地存储的文件path
         */
        fun getDownloadPath(downloadId: Long): String {
            if (downloadManager == null) {
                downloadManager =
                    Utils.getApp().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
            }
            return UriUtils.uri2File(downloadManager!!.getUriForDownloadedFile(downloadId)).absolutePath
        }

        /**
         * 根据downloadID 获取获取本地文件存储的uri
         */
        fun getDownloadUri(downloadId: Long): Uri {
            if (downloadManager == null) {
                downloadManager =
                    Utils.getApp().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
            }
            return downloadManager!!.getUriForDownloadedFile(downloadId)
        }

        /**
         * 下载apk
         */
        fun downloadAPK(url: String, apkName: String): Long {
            val request = DownloadManager.Request(Uri.parse(url))
            request.setAllowedOverRoaming(false)
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
            request.setTitle("下载新版本")
            request.setDescription(AppUtils.getAppName())
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, apkName)
            if (downloadManager == null) {
                downloadManager =
                    Utils.getApp().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
            }
            val downloadId = downloadManager!!.enqueue(request)
            MMKV.defaultMMKV().encode(DOWNLOAD_ID_APK, downloadId)
            return downloadId
        }

        /**
         * 移除本地存储的downloadid 和相关文件
         */
        fun removeDownloadId(downloadId: Long) {
            if (downloadManager == null) {
                downloadManager =
                    Utils.getApp().getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
            }
            downloadManager!!.remove(downloadId)
            MMKV.defaultMMKV().remove(DOWNLOAD_ID_APK)
        }

        /**
         * 安装app
         */
        fun installApp(uri: Uri) {
            val intent = Intent()
            intent.action = Intent.ACTION_VIEW
            intent.setDataAndType(uri, "application/vnd.android.package-archive")
            intent.addCategory(Intent.CATEGORY_DEFAULT)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            Utils.getApp().startActivity(intent)
        }

        /**
         * 安装app
         */
        fun installApp(apkPath: String) {
            val file = File(apkPath)
            var uri: Uri
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                uri = FileProvider.getUriForFile(
                    Utils.getApp(),
                    "${AppUtils.getAppPackageName()}.fileprovider",
                    file
                )
            } else {
                uri = Uri.fromFile(file)
            }
            installApp(uri)
        }
    }

    /**
     * 下载到本地
     *
     * @param body 内容
     * @return 成功或者失败
     */
    fun writeResponseBodyToDisk(body: ResponseBody?, fileName: String?): File? {
        if (body != null && !fileName.isNullOrBlank()) {
            try {
                //创建一个文件
                val futureStudioIconFile =
                    File(
                        Utils.getApp()
                            .getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.absolutePath + File.separator + fileName
                    )
                //初始化输入流
                var inputStream: InputStream? = null
                //初始化输出流
                var outputStream: OutputStream? = null
                try {
                    //设置每次读写的字节
                    val fileReader = ByteArray(4096)
                    val fileSize = body.contentLength()
                    var fileSizeDownloaded: Long = 0
                    //请求返回的字节流
                    inputStream = body.byteStream()
                    //创建输出流
                    outputStream = FileOutputStream(futureStudioIconFile)
                    //进行读取操作
                    while (true) {
                        val read: Int = inputStream.read(fileReader)
                        if (read == -1) {
                            break
                        }
                        //进行写入操作
                        outputStream.write(fileReader, 0, read)
                        fileSizeDownloaded += read.toLong()
                    }

                    //刷新
                    outputStream.flush()
                    if (futureStudioIconFile.exists() && futureStudioIconFile.length() > 0) {
                        return futureStudioIconFile
                    }
                } catch (e: IOException) {
                    LogUtils.e(e.toString())
                } finally {
                    inputStream?.close()
                    outputStream?.close()
                }
            } catch (e: IOException) {
                LogUtils.e(e.toString())
            }
        }
        return null
    }
}